import {defineComponent, type PropType} from "vue";
import {WinLFResize, WinUDResize} from "@layouts/base/window/WindowFunc";
import {useAppStore} from "@/stores";
import WindowContent from "@layouts/base/window/WindowContent";
import "../scss/Window.scss"
import type {DesktopInterface} from "@/typings/desktop";

/**
 * 窗口 组件
 * @date 2023/10/3
 */
export default defineComponent({
  name: "WindowLayout",
  props: {
    app: {
      type: Object as PropType<DesktopInterface.AppShortcut>,
      required: true,
    },
  },
  setup({ app }) {
    // 初始化操作
    onMounted(() => {
      const cpv = currPosition;
      let width = app.width;
      let height = app.height;
      // 让窗口居中
      width != undefined && (cpv.left = cpv.right = (el.value?.clientWidth! - width - 20) >> 1);
      height != undefined && (cpv.top = cpv.bottom = (el.value?.clientHeight! - height - 20) >> 1);
    });
    const el = ref<HTMLElement>();
    // 窗口是否调整大小中
    const isWinResizing = ref(false);
    const isDirectionMove = ref(false);
    // 移动方向的class名字
    const moveTarget = ref("");
    // 是否最大化
    const isMaximizing = ref(false);
    // 是否全屏
    const isFullScreen = ref(false);
    // 窗口是否移动中
    const isWinMoving = ref(false);

    /**
     * 初始、记录定位标记
     */
    const initialPosition: WindowInterface.ElementPosition = reactive({
      left: 0,
      right: 0,
      top: 0,
      bottom: 0,
    });

    /**
     * 当前位置标记
     */
    const currPosition: WindowInterface.ElementPosition = reactive({
      left: 200,
      right: 0,
      top: 100,
      bottom: 0,
    });

    /**
     * 初始、记录坐标
     */
    const initialCoordinate: WindowInterface.ElementCoordinate = reactive({ x: 0, y: 0 });
    const { showThisAppByKey, closeApp, hideApp } = useAppStore();

    /**
     * @description: 返回应用配置的样式类
     */
    function getWinClassProps(): Array<string> {
      const classArr = new Array<string>();

      !isWinResizing.value && !isWinMoving.value && classArr.push("win-animation");
      isMaximizing.value && classArr.push("maximizing-style");
      isFullScreen.value && classArr.push("full-screen-style");
      app.isDisableResize && classArr.push("win-disable-resize");
      app.isTop && classArr.push("is-top");
      return classArr;
    }

    const stopState = () => {
      isWinMoving.value = false;
      isWinResizing.value = false;
      isDirectionMove.value = false;
    };

    /**
     * 鼠标拉伸点击按下触发事件
     * @param e
     */
    const mouseResizingDown = (e: MouseEvent) => {
      if (app.isDisableResize) return;
      if (isFullScreen.value || isMaximizing.value) return;
      switchCoordinate(e);
      isWinResizing.value = true;
      moveTarget.value = (e.target as any).dataset["key"];
    };

    /**
     * 坐标转换 并记录位置
     * @param e
     */
    const switchCoordinate = (e: MouseEvent) => {
      // todo:显示当前应用
      showThisAppByKey(app.key!);
      // 将当前位置复制给初始的位置
      const { left, right, top, bottom } = currPosition;

      initialPosition.left = left;
      initialPosition.right = right;
      initialPosition.top = top;
      initialPosition.bottom = bottom;

      initialCoordinate.x = e.clientX;
      initialCoordinate.y = e.clientY;
    };

    const appMouseMove = (e: MouseEvent) => {
      const cy = e.clientY;
      const cx = e.clientX;
      const { x, y } = initialCoordinate;
      const { left, right, top, bottom } = initialPosition;
      // 防止拖拽出顶部
      let tv = 20;
      if (isWinResizing.value) {
        isFullScreen.value = false;
        isMaximizing.value = false;
        switch (moveTarget.value) {
          case "top-left":
            tv = top + (cy - y);
            currPosition.top = tv <= 20 ? 20 : tv;
            currPosition.left = left + (cx - x);
            break;
          case "top-center":
            tv = top + (cy - y);
            currPosition.top = tv <= 20 ? 20 : tv;
            break;
          case "top-right":
            tv = top + (cy - y);
            currPosition.top = tv <= 20 ? 20 : tv;
            currPosition.right = right - (cx - x);
            break;
          case "bottom-left":
            currPosition.left = left + (cx - x);
            currPosition.bottom = bottom - (cy - y);
            break;
          case "bottom-center":
            currPosition.bottom = bottom - (cy - y);
            break;
          case "bottom-right":
            currPosition.right = right - (cx - x);
            currPosition.bottom = bottom - (cy - y);
            break;
          case "center-left":
            currPosition.left = left + (cx - x);
            break;
          case "center-right":
            currPosition.right = right - (cx - x);
            break;
          default:
        }
        return;
      }

      if (isWinMoving.value) {
        isFullScreen.value = false;
        isMaximizing.value = false;

        currPosition.left = left + (cx - x);
        currPosition.right = right - (cx - x);
        tv = top + (cy - y);
        currPosition.top = tv <= 20 ? 20 : tv;
        currPosition.bottom = bottom - (cy - y);
        return;
      }
    };

    const toFullScreen = () => {
      if (app.isDisableResize) {
        return;
      }
      isFullScreen.value = !isFullScreen.value;
      isMaximizing.value = !!isFullScreen.value;
    };

    const toDblclick = () => {
      if (app.isDisableResize) {
        return;
      }
      isMaximizing.value = !isMaximizing.value;
      if (!isMaximizing.value) {
        isFullScreen.value = false;
      }
    };

    const toMousedown = (e: MouseEvent) => {
      e.stopPropagation();
      if (isFullScreen.value || isMaximizing.value) return;
      switchCoordinate(e);
      isWinMoving.value = true;
    };

    return () => (
      <main
        ref={el}
        id="win-container"
        class="fixed inset-0"
        style={{
          pointerEvents: isWinResizing.value || isWinMoving.value ? "auto" : "none",
          zIndex: isFullScreen.value ? 999 : app.isTop ? 98 : 88,
        }}
        // 鼠标指针移出元素时被触发事件
        onMouseleave={e => {
          e.stopPropagation();
          stopState();
        }}
        // 鼠标的光标在元素内移动时触发事件
        onMousemove={appMouseMove}
        // 鼠标按钮在元素内释放时触发事件
        onMouseup={() => stopState()}
        // 右键点击事件
        onContextmenu={e => e.preventDefault()}
      >
        <div
          class={["win-resize flex flex-col absolute pointer-events-auto", ...getWinClassProps()]}
          style={{
            left: currPosition.left + "px",
            right: currPosition.right + "px",
            top: currPosition.top + "px",
            bottom: currPosition.bottom + "px",
          }}
        >
          <WinUDResize isTop={true} mouseResizing={mouseResizingDown} />

          <div class="win-resize-center flex flex-row grow">
            <WinLFResize isLeft={true} mouseResizing={mouseResizingDown} />

            <WindowContent
              winContent={{
                appKey: app.key,
                component: app.component,
                isLink: app.isLink,
                linkType: app.linkType,
                link: app.link,
                title: app.title,
                titleColor: app.titleColor,
                titleBgColor: app.titleBgColor,
                isDisableResize: app.isDisableResize,
                toMousedown: toMousedown,
                toDblclick: toDblclick,
                toFullScreen: toFullScreen,
                toCloseApp: closeApp,
                toHideApp: hideApp,
                toShowApp: showThisAppByKey,
              }}
            />

            <WinLFResize isLeft={false} mouseResizing={mouseResizingDown} />
          </div>
          <WinUDResize mouseResizing={mouseResizingDown} isTop={false} />
        </div>
      </main>
    );
  },
});
